package com.token.domino;
import java.util.Vector;
import com.alibaba.fastjson.JSONObject;
import com.token.base.FuncUtil;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.DocumentCollection;
import lotus.domino.NotesException;
import lotus.domino.View;
import lotus.domino.Item;
import lotus.domino.ViewEntryCollection;
/**
 * Domino处理类
 * @author chenjianxiong 2020/2/15
 */
public class DominoFuncUtil{
    Database appDb = null;
    Document appDoc = null;
    Database db = null;
    Document doc = null;
    View view = null;
    FuncUtil funcUtil;
    /**
     * 构造函数
     * @param f FuncUtil
     * @throws NotesException 错误信息
     */
    public DominoFuncUtil(FuncUtil f) throws NotesException{
        db = f.getCurDb();
        doc = f.getCurDoc();
        funcUtil = f;
    }



    /**
     * 返回当前操作文档对象。
     * @return Document
     */
    public Document getFuncAppDoc(){
        return this.appDoc;
    }



    /**
     * 文档字段转JSON输出
     * @param doc 文档对象
     * @return JSONObject
     * @throws NotesException 错误信息
     */
    public JSONObject documentSetToJsonObject(Document doc) throws NotesException{
        JSONObject json = new JSONObject();
        if(doc == null){
            return null;
        }else{
            Vector<?> items = doc.getItems();
            for (int j=0; j<items.size(); j++) {
                Item item = (Item)items.elementAt(j);
                String name = item.getName();
                Vector<?> ect = item.getValues();
                if( ect != null && !name.contains("$")){
                    if(ect.size() == 1){
                        json.put(name, ect.get(0));
                    }else{
                        json.put(name, ect);
                    }
                }
            }
        }
        return json;
    }

    /**
     * 打开指定数据库的视图
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @return View
     * @throws NotesException 错误信息
     */
    public View openView(Database appDb,String viewName) throws NotesException{
        if(appDb == null){
            System.out.println("数据库无法打开，请检查！");
            return null;
        }
        View view = appDb.getView(viewName);
        view.setAutoUpdate(false);
        return view;
    }
    /**
     * 打开当前数据库的视图
     * @param viewName 视图名
     * @return View
     * @throws NotesException 错误信息
     */
    public View openView(String viewName) throws NotesException{
        return openView(db,viewName);
    }

    /**
     * 打开指定数据库文件名的视图
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @return View
     * @throws Exception 错误抛出
     */
    public View openView(String dbName,String viewName) throws Exception{
        appDb = funcUtil.openDb(dbName);
        if(appDb == null){
            throw new Exception("无法打开数据库["+ dbName +"]");
        }
        return openView(appDb,viewName);
    }

    /**
     * 释放Domino对象
     */
    public void recycle(){
        try{
            if(view != null) {view.recycle();}
            if(appDb != null) {appDb.recycle();}
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 根据key获取多条文档,返回文档集合
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return DocumentCollection
     * @throws NotesException 错误信息
     */
    public  DocumentCollection getAllDocumentsByKey(Database appDb,String viewName,String searchKey,boolean exact) throws NotesException{
        view = openView(appDb, viewName);
        return view.getAllDocumentsByKey(searchKey,exact);
    }
    /**
     * 根据key获取多条文档,返回文档集合
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return DocumentCollection
     * @throws NotesException 错误信息
     */
    public DocumentCollection getAllDocumentsByKey(Database appDb,String viewName,Vector<String> searchKeys,boolean exact) throws NotesException{
        view = openView(appDb, viewName);
        return view.getAllDocumentsByKey(searchKeys,exact);
    }

    /**
     * 根据key获取多条文档,返回文档集合
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return DocumentCollection
     * @throws Exception 错误抛出
     */
    public DocumentCollection getAllDocumentsByKey(String viewName,Vector<String> searchKeys,boolean exact) throws Exception{
        return this.getAllDocumentsByKey(db, viewName, searchKeys,true);
    }

    /**
     * 根据key获取多条文档,返回文档集合
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return DocumentCollection
     * @throws Exception 错误抛出
     */
    public DocumentCollection getAllDocumentsByKey(String viewName,String searchKey,boolean exact) throws Exception{
        return this.getAllDocumentsByKey(db, viewName, searchKey, true);
    }

    /**
     * 根据key获取多条文档,返回文档集合
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return DocumentCollection
     * @throws Exception 错误抛出
     */
    public DocumentCollection getAllDocumentsByKey(String dbName,String viewName,Vector<String> searchKeys,boolean exact) throws Exception{
        openAppDb(dbName);
        return this.getAllDocumentsByKey(appDb, viewName, searchKeys,true);
    }

    /**
     * 根据key获取多条文档,返回文档集合
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return DocumentCollection
     * @throws Exception 错误抛出
     */
    public DocumentCollection getAllDocumentsByKey(String dbName,String viewName,String searchKey,boolean exact) throws Exception{
        openAppDb(dbName);
        return this.getAllDocumentsByKey(appDb, viewName, searchKey,true);
    }

    /**
     * 根据key获取多条文档
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return ViewEntryCollection
     * @throws Exception 错误抛出
     */
    public ViewEntryCollection getAllEntriesByKey(Database appDb,String viewName,Vector<String> searchKeys,boolean exact) throws Exception{
        view = openView(appDb, viewName);
        return view.getAllEntriesByKey(searchKeys,exact);
    }
    /**
     * 根据key获取多条行
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return ViewEntryCollection
     * @throws Exception 错误抛出
     */
    public ViewEntryCollection getAllEntriesBykey(Database appDb,String viewName,String searchKey,boolean exact) throws Exception{
        view = openView(appDb, viewName);
        return view.getAllEntriesByKey(searchKey,exact);
    }
    /**
     * 根据key获取多条文档,返回文档集合
     * @param dbName 数据库名称，不含目录名
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return ViewEntryCollection
     * @throws Exception 错误抛出
     */
    public ViewEntryCollection getAllEntriesBykey(String dbName,String viewName,Vector<String> searchKeys,boolean exact) throws Exception{
        openAppDb(dbName);
        return this.getAllEntriesByKey(appDb, viewName, searchKeys, true);
    }
    /**
     * 根据key获取多条文档,返回文档集合
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return ViewEntryCollection
     * @throws Exception 错误抛出
     */
    public ViewEntryCollection getAllEntriesByKey(String dbName,String viewName,String searchKey,boolean exact) throws Exception{
        openAppDb(dbName);
        return this.getAllEntriesBykey(appDb, viewName, searchKey, true);
    }
    /**
     * 根据key获取多条文档,返回文档集合
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return ViewEntryCollection
     * @throws Exception 错误抛出
     */
    public ViewEntryCollection getAllEntriesByKey(String viewName,String searchKey,boolean exact) throws Exception{
        view = openView(db, viewName);
        return view.getAllEntriesByKey(searchKey,exact);
    }
    /**
     * 根据key获取多条文档,返回文档集合
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return ViewEntryCollection
     * @throws Exception 错误抛出
     */
    public ViewEntryCollection getAllEntriesByKey(String viewName,Vector<String> searchKeys,boolean exact) throws Exception{
        view = openView(db, viewName);
        return view.getAllEntriesByKey(searchKeys,exact);
    }

    /**
     *
     * @param viewName 视图名
     * @return ViewEntryCollection
     * @throws NotesException 错误信息
     */
    public ViewEntryCollection getAllEntries(String viewName) throws NotesException{
        view = openView(db, viewName);
        return view.getAllEntries();
    }

    /**
     *
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @return ViewEntryCollection
     * @throws NotesException 错误信息
     */
    public ViewEntryCollection getAllEntries(Database appDb,String viewName) throws NotesException{
        view = openView(appDb, viewName);
        return view.getAllEntries();
    }

    /**
     *
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @return ViewEntryCollection
     * @throws NotesException 错误信息
     */
    public ViewEntryCollection getAllEntries(String dbName,String viewName) throws NotesException{
        openAppDb(dbName);
        view = openView(appDb, viewName);
        return view.getAllEntries();
    }

    /**
     * 根据key获取指定数据库下的单条文档
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return Document
     * @throws NotesException 错误信息
     */
    public  Document getDocumentByKey(Database appDb,String viewName,Vector<String> searchKeys,boolean exact) throws NotesException{
        view = openView(appDb, viewName);
        return view.getDocumentByKey(searchKeys, exact);
    }
    /**
     * 根据key获取指定数据库下的单条文档
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return Document
     * @throws NotesException 错误信息
     */
    public Document getDocumentByKey(Database appDb,String viewName,String searchKey,boolean exact) throws NotesException{
        if(appDb == null){
            throw new RuntimeException("传入的数据库为空值！");
        }
        view = openView(appDb, viewName);

        if(view == null){
            throw new RuntimeException(appDb.getFileName() +"的视图不存在："+ viewName);
        }
        return view.getDocumentByKey(searchKey, exact);
    }
    /**
     * 根据key获取当前数据库的单条文档
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return Document
     * @throws NotesException 错误信息
     */
    public Document getDocumentByKey(String viewName,String searchKey,boolean exact) throws NotesException{
        return this.getDocumentByKey(db, viewName, searchKey, exact);
    }

    /**
     *
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return Document
     * @throws NotesException 错误信息
     */
    public Document getDocumentByKey(String viewName,Vector<String> searchKeys,boolean exact) throws NotesException{
        return this.getDocumentByKey(db, viewName, searchKeys, exact);
    }

    /**
     *
     * @param view 视图对象
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return Document
     * @throws NotesException 错误信息
     */
    public Document getDocumentByKey(View view,String searchKeys, boolean exact) throws NotesException {
        return view.getDocumentByKey(searchKeys, exact);
    }
    /**
     * 根据key获取单条文档
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param exact true 精确搜索 false 模糊搜索
     * @return Document
     * @throws NotesException 错误信息
     */
    public Document getDocumentByKey(String dbName,String viewName,String searchKey,boolean exact) throws NotesException{
        openAppDb(dbName);
        if(appDb == null){
            System.out.println("getDocumentByKey 函数的数据库对象为空值！");
            return null;
        }
        return this.getDocumentByKey(appDb, viewName, searchKey, true);
    }
    /**
     * 根据key获取单条文档
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @param searchKeys 搜索数组Vector
     * @param exact true 精确搜索 false 模糊搜索
     * @return Document
     * @throws Exception 错误抛出
     */
    public Document getDocumentByKey(String dbName,String viewName,Vector<String> searchKeys,boolean exact) throws Exception{
        openAppDb(dbName);
        if(appDb == null){
            System.out.println("getDocumentByKey 函数的数据库对象为空值！");
            return null;
        }
        return this.getDocumentByKey(appDb, viewName, searchKeys, true);
    }

    /**
     * 根据UNID从当前数据库中获取文档。
     * @param dbName  数据库名称，不含目录名
     * @param unid UNID
     * @return Document
     * @throws NotesException 错误信息
     */
    public Document getDocumentByUNID(String dbName,String unid) throws NotesException{
        openAppDb(dbName);
        if(appDb == null){
            System.out.println("getDocumentByUNID 函数的数据库对象为空值！");
            return null;
        }
        return appDb.getDocumentByUNID(unid);
    }

    /**
     *
     * @param dbName  数据库名称，不含目录名
     * @param notesID notesID
     * @return Document
     * @throws NotesException 错误信息
     */
    public Document getDocumentByID(String dbName,String notesID) throws NotesException{
        openAppDb(dbName);
        if(appDb == null){
            System.out.println("getDocumentByUNID 函数的数据库对象为空值！");
            return null;
        }
        return appDb.getDocumentByID(notesID);
    }

    /**
     * 根据UNID从当前数据库中获取文档。
     * @param unid UNID
     * @return Document
     * @throws NotesException 错误信息
     */
    public Document getDocumentByUNID(String unid) throws NotesException{
        return db.getDocumentByUNID(unid);
    }
    /**
     * 获取字段值
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param fieldName 字段名
     * @return String
     * @throws NotesException 错误信息
     */
    public String getItemValueString(String dbName,String viewName,String searchKey,String fieldName) throws NotesException{
        appDoc = this.getDocumentByKey(dbName, viewName, searchKey, true);
        if(appDoc == null){
            System.out.println("getItemValueString 的文档对象为空值！");
            return null;
        }
        return appDoc.getItemValueString(fieldName);
    }
    /**
     * 获取字段值
     * @param db 数据库对象
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param fieldName 字段名
     * @return String
     * @throws NotesException 错误信息
     */
    public String getItemValueString(Database db,String viewName,String searchKey,String fieldName) throws NotesException{
        appDoc = this.getDocumentByKey(db, viewName, searchKey, true);
        return appDoc.getItemValueString(fieldName);
    }

    /**
     * 获取字段值
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param fieldName 字段名
     * @return String
     * @throws NotesException 错误信息
     */
    public String getItemValueString(String viewName,String searchKey,String fieldName) throws NotesException{
        appDoc = this.getDocumentByKey(viewName, searchKey, true);
        return appDoc.getItemValueString(fieldName);
    }

    /**
     *
     * @param view 视图对象
     * @param searchKey 搜索值
     * @param fieldName 字段名
     * @return String
     * @throws NotesException 错误信息
     */
    public String getItemValueString(View view,String searchKey,String fieldName) throws NotesException{
        appDoc = view.getDocumentByKey(searchKey,true);
        if(appDoc == null){
            System.out.println("在"+ view.getName() + "中找不到：" + searchKey );
            return null;
        }
        return appDoc.getItemValueString(fieldName);
    }

    /**
     *
     * @param view 视图对象
     * @param searchKeys 搜索数组Vector
     * @param fieldName 字段名
     * @return String
     * @throws NotesException 错误信息
     */
    public String getItemValueString(View view,Vector<String> searchKeys,String fieldName) throws NotesException{
        appDoc = view.getDocumentByKey(searchKeys,true);
        return appDoc.getItemValueString(fieldName);
    }
    /**
     *
     * @param fieldName 字段名
     * @return String
     * @throws NotesException 错误信息
     */
    public String getItemValueString(String fieldName) throws NotesException{
        return appDoc.getItemValueString(fieldName);
    }
    /**
     * 获取字段值的数组
     * @param dbName  数据库名称，不含目录名
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param fieldName 字段名
     * @return Vector
     * @throws NotesException 错误信息
     */

    public Vector<?> getItemValue(String dbName,String viewName,String searchKey,String fieldName) throws NotesException{
        appDoc = this.getDocumentByKey(dbName, viewName, searchKey, true);
        return appDoc.getItemValue(fieldName);
    }

    /**
     * 获取字段值的数组
     * @param appDb 数据库对象
     * @param viewName 视图名
     * @param searchKey 搜索值
     * @param fieldName 字段名
     * @return Vector
     * @throws NotesException 错误信息
     */
    public Vector<?> getItemValue(Database appDb,String viewName,String searchKey,String fieldName) throws NotesException{
        appDoc = this.getDocumentByKey(appDb, viewName, searchKey, true);
        return appDoc.getItemValue(fieldName);
    }

    /**
     * 打开数据库，如果已经打开则判断是否重复。
     * @param dbName 数据库，不包含目录
     * @throws NotesException 错误信息
     */
    private void openAppDb(String dbName) throws NotesException{
        if(appDb == null){
            appDb = funcUtil.openDb(dbName);
        }else{
            if(!dbName.toLowerCase().equals(appDb.getFileName().toLowerCase())){
                appDb = funcUtil.openDb(dbName);
            }
        }
    }
}
